home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Modules / structmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-10  |  24.5 KB  |  1,349 lines

  1. /* struct module -- pack values into and (out of) strings */
  2.  
  3. /* New version supporting byte order, alignment and size options,
  4.    character strings, and unsigned numbers */
  5.  
  6. static char struct__doc__[] = "\
  7. Functions to convert between Python values and C structs.\n\
  8. Python strings are used to hold the data representing the C struct\n\
  9. and also as format strings to describe the layout of data in the C struct.\n\
  10. \n\
  11. The optional first format char indicates byte ordering and alignment:\n\
  12.  @: native w/native alignment(default)\n\
  13.  =: native w/standard alignment\n\
  14.  <: little-endian, std. alignment\n\
  15.  >: big-endian, std. alignment\n\
  16.  !: network, std (same as >)\n\
  17. \n\
  18. The remaining chars indicate types of args and must match exactly;\n\
  19. these can be preceded by a decimal repeat count:\n\
  20.  x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
  21.  h:short; H:unsigned short; i:int; I:unsigned int;\n\
  22.  l:long; L:unsigned long; f:float; d:double.\n\
  23. Special cases (preceding decimal count indicates length):\n\
  24.  s:string (array of char); p: pascal string (w. count byte).\n\
  25. Special case (only available in native format):\n\
  26.  P:an integer type that is wide enough to hold a pointer.\n\
  27. Whitespace between formats is ignored.\n\
  28. \n\
  29. The variable struct.error is an exception raised on errors.";
  30.  
  31. #include "Python.h"
  32. #include "mymath.h"
  33.  
  34. #include <limits.h>
  35. #include <ctype.h>
  36.  
  37. #include "protos/structmodule.h"
  38.  
  39. /* Exception */
  40.  
  41. static PyObject *StructError;
  42.  
  43.  
  44. /* Define various structs to figure out the alignments of types */
  45.  
  46. #ifdef __MWERKS__
  47. /*
  48. ** XXXX We have a problem here. There are no unique alignment rules
  49. ** on the PowerPC mac. 
  50. */
  51. #ifdef __powerc
  52. #pragma options align=mac68k
  53. #endif
  54. #endif /* __MWERKS__ */
  55.  
  56. typedef struct { char c; short x; } s_short;
  57. typedef struct { char c; int x; } s_int;
  58. typedef struct { char c; long x; } s_long;
  59. typedef struct { char c; float x; } s_float;
  60. typedef struct { char c; double x; } s_double;
  61. typedef struct { char c; void *x; } s_void_p;
  62.  
  63. #define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
  64. #define INT_ALIGN (sizeof(s_int) - sizeof(int))
  65. #define LONG_ALIGN (sizeof(s_long) - sizeof(long))
  66. #define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
  67. #define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
  68. #define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *))
  69.  
  70. #ifdef __powerc
  71. #pragma options align=reset
  72. #endif
  73.  
  74. /* Helper routine to get a Python integer and raise the appropriate error
  75.    if it isn't one */
  76.  
  77. static int
  78. get_long(v, p)
  79.     PyObject *v;
  80.     long *p;
  81. {
  82.     long x = PyInt_AsLong(v);
  83.     if (x == -1 && PyErr_Occurred()) {
  84.         if (PyErr_ExceptionMatches(PyExc_TypeError))
  85.             PyErr_SetString(StructError,
  86.                     "required argument is not an integer");
  87.         return -1;
  88.     }
  89.     *p = x;
  90.     return 0;
  91. }
  92.  
  93.  
  94. /* Same, but handling unsigned long */
  95.  
  96. static int
  97. get_ulong(v, p)
  98.     PyObject *v;
  99.     unsigned long *p;
  100. {
  101.     if (PyLong_Check(v)) {
  102.         unsigned long x = PyLong_AsUnsignedLong(v);
  103.         if (x == (unsigned long)(-1) && PyErr_Occurred())
  104.             return -1;
  105.         *p = x;
  106.         return 0;
  107.     }
  108.     else {
  109.         return get_long(v, (long *)p);
  110.     }
  111. }
  112.  
  113.  
  114. /* Floating point helpers */
  115.  
  116. /* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
  117.    Point Arithmetic).  See the following URL:
  118.    http://www.psc.edu/general/software/packages/ieee/ieee.html */
  119.  
  120. /* XXX Inf/NaN are not handled quite right (but underflow is!) */
  121.  
  122. static int
  123. pack_float(x, p, incr)
  124.     double x; /* The number to pack */
  125.     char *p;  /* Where to pack the high order byte */
  126.     int incr; /* 1 for big-endian; -1 for little-endian */
  127. {
  128.     int s;
  129.     int e;
  130.     double f;
  131.     long fbits;
  132.  
  133.     if (x < 0) {
  134.         s = 1;
  135.         x = -x;
  136.     }
  137.     else
  138.         s = 0;
  139.  
  140.     f = frexp(x, &e);
  141.  
  142.     /* Normalize f to be in the range [1.0, 2.0) */
  143.     if (0.5 <= f && f < 1.0) {
  144.         f *= 2.0;
  145.         e--;
  146.     }
  147.     else if (f == 0.0) {
  148.         e = 0;
  149.     }
  150.     else {
  151.         PyErr_SetString(PyExc_SystemError,
  152.                 "frexp() result out of range");
  153.         return -1;
  154.     }
  155.  
  156.     if (e >= 128) {
  157.         /* XXX 128 itself is reserved for Inf/NaN */
  158.         PyErr_SetString(PyExc_OverflowError,
  159.                 "float too large to pack with f format");
  160.         return -1;
  161.     }
  162.     else if (e < -126) {
  163.         /* Gradual underflow */
  164.         f = ldexp(f, 126 + e);
  165.         e = 0;
  166.     }
  167.     else if (!(e == 0 && f == 0.0)) {
  168.         e += 127;
  169.         f -= 1.0; /* Get rid of leading 1 */
  170.     }
  171.  
  172.     f *= 8388608.0; /* 2**23 */
  173.     fbits = (long) floor(f + 0.5); /* Round */
  174.  
  175.     /* First byte */
  176.     *p = (s<<7) | (e>>1);
  177.     p += incr;
  178.  
  179.     /* Second byte */
  180.     *p = (char) (((e&1)<<7) | (fbits>>16));
  181.     p += incr;
  182.  
  183.     /* Third byte */
  184.     *p = (fbits>>8) & 0xFF;
  185.     p += incr;
  186.  
  187.     /* Fourth byte */
  188.     *p = fbits&0xFF;
  189.  
  190.     /* Done */
  191.     return 0;
  192. }
  193.  
  194. static int
  195. pack_double(x, p, incr)
  196.     double x; /* The number to pack */
  197.     char *p;  /* Where to pack the high order byte */
  198.     int incr; /* 1 for big-endian; -1 for little-endian */
  199. {
  200.     int s;
  201.     int e;
  202.     double f;
  203.     long fhi, flo;
  204.  
  205.     if (x < 0) {
  206.         s = 1;
  207.         x = -x;
  208.     }
  209.     else
  210.         s = 0;
  211.  
  212.     f = frexp(x, &e);
  213.  
  214.     /* Normalize f to be in the range [1.0, 2.0) */
  215.     if (0.5 <= f && f < 1.0) {
  216.         f *= 2.0;
  217.         e--;
  218.     }
  219.     else if (f == 0.0) {
  220.         e = 0;
  221.     }
  222.     else {
  223.         PyErr_SetString(PyExc_SystemError,
  224.                 "frexp() result out of range");
  225.         return -1;
  226.     }
  227.  
  228.     if (e >= 1024) {
  229.         /* XXX 1024 itself is reserved for Inf/NaN */
  230.         PyErr_SetString(PyExc_OverflowError,
  231.                 "float too large to pack with d format");
  232.         return -1;
  233.     }
  234.     else if (e < -1022) {
  235.         /* Gradual underflow */
  236.         f = ldexp(f, 1022 + e);
  237.         e = 0;
  238.     }
  239.     else if (!(e == 0 && f == 0.0)) {
  240.         e += 1023;
  241.         f -= 1.0; /* Get rid of leading 1 */
  242.     }
  243.  
  244.     /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
  245.     f *= 268435456.0; /* 2**28 */
  246.     fhi = (long) floor(f); /* Truncate */
  247.     f -= (double)fhi;
  248.     f *= 16777216.0; /* 2**24 */
  249.     flo = (long) floor(f + 0.5); /* Round */
  250.  
  251.     /* First byte */
  252.     *p = (s<<7) | (e>>4);
  253.     p += incr;
  254.  
  255.     /* Second byte */
  256.     *p = (char) (((e&0xF)<<4) | (fhi>>24));
  257.     p += incr;
  258.  
  259.     /* Third byte */
  260.     *p = (fhi>>16) & 0xFF;
  261.     p += incr;
  262.  
  263.     /* Fourth byte */
  264.     *p = (fhi>>8) & 0xFF;
  265.     p += incr;
  266.  
  267.     /* Fifth byte */
  268.     *p = fhi & 0xFF;
  269.     p += incr;
  270.  
  271.     /* Sixth byte */
  272.     *p = (flo>>16) & 0xFF;
  273.     p += incr;
  274.  
  275.     /* Seventh byte */
  276.     *p = (flo>>8) & 0xFF;
  277.     p += incr;
  278.  
  279.     /* Eighth byte */
  280.     *p = flo & 0xFF;
  281.     p += incr;
  282.  
  283.     /* Done */
  284.     return 0;
  285. }
  286.  
  287. static PyObject *
  288. unpack_float(p, incr)
  289.     char *p;  /* Where the high order byte is */
  290.     int incr; /* 1 for big-endian; -1 for little-endian */
  291. {
  292.     int s;
  293.     int e;
  294.     long f;
  295.     double x;
  296.  
  297.     /* First byte */
  298.     s = (*p>>7) & 1;
  299.     e = (*p & 0x7F) << 1;
  300.     p += incr;
  301.  
  302.     /* Second byte */
  303.     e |= (*p>>7) & 1;
  304.     f = (*p & 0x7F) << 16;
  305.     p += incr;
  306.  
  307.     /* Third byte */
  308.     f |= (*p & 0xFF) << 8;
  309.     p += incr;
  310.  
  311.     /* Fourth byte */
  312.     f |= *p & 0xFF;
  313.  
  314.     x = (double)f / 8388608.0;
  315.  
  316.     /* XXX This sadly ignores Inf/NaN issues */
  317.     if (e == 0)
  318.         e = -126;
  319.     else {
  320.         x += 1.0;
  321.         e -= 127;
  322.     }
  323.     x = ldexp(x, e);
  324.  
  325.     if (s)
  326.         x = -x;
  327.  
  328.     return PyFloat_FromDouble(x);
  329. }
  330.  
  331. static PyObject *
  332. unpack_double(p, incr)
  333.     char *p;  /* Where the high order byte is */
  334.     int incr; /* 1 for big-endian; -1 for little-endian */
  335. {
  336.     int s;
  337.     int e;
  338.     long fhi, flo;
  339.     double x;
  340.  
  341.     /* First byte */
  342.     s = (*p>>7) & 1;
  343.     e = (*p & 0x7F) << 4;
  344.     p += incr;
  345.  
  346.     /* Second byte */
  347.     e |= (*p>>4) & 0xF;
  348.     fhi = (*p & 0xF) << 24;
  349.     p += incr;
  350.  
  351.     /* Third byte */
  352.     fhi |= (*p & 0xFF) << 16;
  353.     p += incr;
  354.  
  355.     /* Fourth byte */
  356.     fhi |= (*p & 0xFF) << 8;
  357.     p += incr;
  358.  
  359.     /* Fifth byte */
  360.     fhi |= *p & 0xFF;
  361.     p += incr;
  362.  
  363.     /* Sixth byte */
  364.     flo = (*p & 0xFF) << 16;
  365.     p += incr;
  366.  
  367.     /* Seventh byte */
  368.     flo |= (*p & 0xFF) << 8;
  369.     p += incr;
  370.  
  371.     /* Eighth byte */
  372.     flo |= *p & 0xFF;
  373.     p += incr;
  374.  
  375.     x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
  376.     x /= 268435456.0; /* 2**28 */
  377.  
  378.     /* XXX This sadly ignores Inf/NaN */
  379.     if (e == 0)
  380.         e = -1022;
  381.     else {
  382.         x += 1.0;
  383.         e -= 1023;
  384.     }
  385.     x = ldexp(x, e);
  386.  
  387.     if (s)
  388.         x = -x;
  389.  
  390.     return PyFloat_FromDouble(x);
  391. }
  392.  
  393.  
  394. /* The translation function for each format character is table driven */
  395.  
  396. typedef struct _formatdef {
  397.     char format;
  398.     int size;
  399.     int alignment;
  400.     PyObject* (*unpack) Py_PROTO((const char *,
  401.                       const struct _formatdef *));
  402.     int (*pack) Py_PROTO((char *,
  403.                   PyObject *,
  404.                   const struct _formatdef *));
  405. } formatdef;
  406.  
  407. #include "protos/structmodule2.h"
  408.  
  409. static PyObject *
  410. nu_char(p, f)
  411.     const char *p;
  412.     const formatdef *f;
  413. {
  414.     return PyString_FromStringAndSize(p, 1);
  415. }
  416.  
  417. static PyObject *
  418. nu_byte(p, f)
  419.     const char *p;
  420.     const formatdef *f;
  421. {
  422.     return PyInt_FromLong((long) *(signed char *)p);
  423. }
  424.  
  425. static PyObject *
  426. nu_ubyte(p, f)
  427.     const char *p;
  428.     const formatdef *f;
  429. {
  430.     return PyInt_FromLong((long) *(unsigned char *)p);
  431. }
  432.  
  433. static PyObject *
  434. nu_short(p, f)
  435.     const char *p;
  436.     const formatdef *f;
  437. {
  438.     return PyInt_FromLong((long) *(short *)p);
  439. }
  440.  
  441. static PyObject *
  442. nu_ushort(p, f)
  443.     const char *p;
  444.     const formatdef *f;
  445. {
  446.     return PyInt_FromLong((long) *(unsigned short *)p);
  447. }
  448.  
  449. static PyObject *
  450. nu_int(p, f)
  451.     const char *p;
  452.     const formatdef *f;
  453. {
  454.     return PyInt_FromLong((long) *(int *)p);
  455. }
  456.  
  457. static PyObject *
  458. nu_uint(p, f)
  459.     const char *p;
  460.     const formatdef *f;
  461. {
  462.     unsigned int x = *(unsigned int *)p;
  463.     return PyLong_FromUnsignedLong((unsigned long)x);
  464. }
  465.  
  466. static PyObject *
  467. nu_long(p, f)
  468.     const char *p;
  469.     const formatdef *f;
  470. {
  471.     return PyInt_FromLong(*(long *)p);
  472. }
  473.  
  474. static PyObject *
  475. nu_ulong(p, f)
  476.     const char *p;
  477.     const formatdef *f;
  478. {
  479.     return PyLong_FromUnsignedLong(*(unsigned long *)p);
  480. }
  481.  
  482. static PyObject *
  483. nu_float(p, f)
  484.     const char *p;
  485.     const formatdef *f;
  486. {
  487.     float x;
  488.     memcpy((char *)&x, p, sizeof(float));
  489.     return PyFloat_FromDouble((double)x);
  490. }
  491.  
  492. static PyObject *
  493. nu_double(p, f)
  494.     const char *p;
  495.     const formatdef *f;
  496. {
  497.     double x;
  498.     memcpy((char *)&x, p, sizeof(double));
  499.     return PyFloat_FromDouble(x);
  500. }
  501.  
  502. static PyObject *
  503. nu_void_p(p, f)
  504.     const char *p;
  505.     const formatdef *f;
  506. {
  507.     return PyLong_FromVoidPtr(*(void **)p);
  508. }
  509.  
  510. static int
  511. np_byte(p, v, f)
  512.     char *p;
  513.     PyObject *v;
  514.     const formatdef *f;
  515. {
  516.     long x;
  517.     if (get_long(v, &x) < 0)
  518.         return -1;
  519.     *p = (char)x;
  520.     return 0;
  521. }
  522.  
  523. static int
  524. np_char(p, v, f)
  525.     char *p;
  526.     PyObject *v;
  527.     const formatdef *f;
  528. {
  529.     if (!PyString_Check(v) || PyString_Size(v) != 1) {
  530.         PyErr_SetString(StructError,
  531.                 "char format require string of length 1");
  532.         return -1;
  533.     }
  534.     *p = *PyString_AsString(v);
  535.     return 0;
  536. }
  537.  
  538. static int
  539. np_short(p, v, f)
  540.     char *p;
  541.     PyObject *v;
  542.     const formatdef *f;
  543. {
  544.     long x;
  545.     if (get_long(v, &x) < 0)
  546.         return -1;
  547.     * (short *)p = (short)x;
  548.     return 0;
  549. }
  550.  
  551. static int
  552. np_int(p, v, f)
  553.     char *p;
  554.     PyObject *v;
  555.     const formatdef *f;
  556. {
  557.     long x;
  558.     if (get_long(v, &x) < 0)
  559.         return -1;
  560.     * (int *)p = x;
  561.     return 0;
  562. }
  563.  
  564. static int
  565. np_uint(p, v, f)
  566.     char *p;
  567.     PyObject *v;
  568.     const formatdef *f;
  569. {
  570.     unsigned long x;
  571.     if (get_ulong(v, &x) < 0)
  572.         return -1;
  573.     * (unsigned int *)p = x;
  574.     return 0;
  575. }
  576.  
  577. static int
  578. np_long(p, v, f)
  579.     char *p;
  580.     PyObject *v;
  581.     const formatdef *f;
  582. {
  583.     long x;
  584.     if (get_long(v, &x) < 0)
  585.         return -1;
  586.     * (long *)p = x;
  587.     return 0;
  588. }
  589.  
  590. static int
  591. np_ulong(p, v, f)
  592.     char *p;
  593.     PyObject *v;
  594.     const formatdef *f;
  595. {
  596.     unsigned long x;
  597.     if (get_ulong(v, &x) < 0)
  598.         return -1;
  599.     * (unsigned long *)p = x;
  600.     return 0;
  601. }
  602.  
  603. static int
  604. np_float(p, v, f)
  605.     char *p;
  606.     PyObject *v;
  607.     const formatdef *f;
  608. {
  609.     float x = (float)PyFloat_AsDouble(v);
  610.     if (x == -1 && PyErr_Occurred()) {
  611.         PyErr_SetString(StructError,
  612.                 "required argument is not a float");
  613.         return -1;
  614.     }
  615.     memcpy(p, (char *)&x, sizeof(float));
  616.     return 0;
  617. }
  618.  
  619. static int
  620. np_double(p, v, f)
  621.     char *p;
  622.     PyObject *v;
  623.     const formatdef *f;
  624. {
  625.     double x = PyFloat_AsDouble(v);
  626.     if (x == -1 && PyErr_Occurred()) {
  627.         PyErr_SetString(StructError,
  628.                 "required argument is not a float");
  629.         return -1;
  630.     }
  631.     memcpy(p, (char *)&x, sizeof(double));
  632.     return 0;
  633. }
  634.  
  635. static int
  636. np_void_p(p, v, f)
  637.     char *p;
  638.     PyObject *v;
  639.     const formatdef *f;
  640. {
  641.     void *x = PyLong_AsVoidPtr(v);
  642.     if (x == NULL && PyErr_Occurred()) {
  643.         /* ### hrm. PyLong_AsVoidPtr raises SystemError */
  644.         if (PyErr_ExceptionMatches(PyExc_TypeError))
  645.             PyErr_SetString(StructError,
  646.                     "required argument is not an integer");
  647.         return -1;
  648.     }
  649.     *(void **)p = x;
  650.     return 0;
  651. }
  652.  
  653. static formatdef native_table[] = {
  654.     {'x',    sizeof(char),    0,        NULL},
  655.     {'b',    sizeof(char),    0,        nu_byte,    np_byte},
  656.     {'B',    sizeof(char),    0,        nu_ubyte,    np_byte},
  657.     {'c',    sizeof(char),    0,        nu_char,    np_char},
  658.     {'s',    sizeof(char),    0,        NULL},
  659.     {'p',    sizeof(char),    0,        NULL},
  660.     {'h',    sizeof(short),    SHORT_ALIGN,    nu_short,    np_short},
  661.     {'H',    sizeof(short),    SHORT_ALIGN,    nu_ushort,    np_short},
  662.     {'i',    sizeof(int),    INT_ALIGN,    nu_int,        np_int},
  663.     {'I',    sizeof(int),    INT_ALIGN,    nu_uint,    np_uint},
  664.     {'l',    sizeof(long),    LONG_ALIGN,    nu_long,    np_long},
  665.     {'L',    sizeof(long),    LONG_ALIGN,    nu_ulong,    np_ulong},
  666.     {'f',    sizeof(float),    FLOAT_ALIGN,    nu_float,    np_float},
  667.     {'d',    sizeof(double),    DOUBLE_ALIGN,    nu_double,    np_double},
  668.     {'P',    sizeof(void *),    VOID_P_ALIGN,    nu_void_p,    np_void_p},
  669.     {0}
  670. };
  671.  
  672. static PyObject *
  673. bu_int(p, f)
  674.     const char *p;
  675.     const formatdef *f;
  676. {
  677.     long x = 0;
  678.     int i = f->size;
  679.     do {
  680.         x = (x<<8) | (*p++ & 0xFF);
  681.     } while (--i > 0);
  682.     i = 8*(sizeof(long) - f->size);
  683.     if (i) {
  684.         x <<= i;
  685.         x >>= i;
  686.     }
  687.     return PyInt_FromLong(x);
  688. }
  689.  
  690. static PyObject *
  691. bu_uint(p, f)
  692.     const char *p;
  693.     const formatdef *f;
  694. {
  695.     unsigned long x = 0;
  696.     int i = f->size;
  697.     do {
  698.         x = (x<<8) | (*p++ & 0xFF);
  699.     } while (--i > 0);
  700.     if (f->size >= 4)
  701.         return PyLong_FromUnsignedLong(x);
  702.     else
  703.         return PyInt_FromLong((long)x);
  704. }
  705.  
  706. static PyObject *
  707. bu_float(p, f)
  708.     const char *p;
  709.     const formatdef *f;
  710. {
  711.     return unpack_float(p, 1);
  712. }
  713.  
  714. static PyObject *
  715. bu_double(p, f)
  716.     const char *p;
  717.     const formatdef *f;
  718. {
  719.     return unpack_double(p, 1);
  720. }
  721.  
  722. static int
  723. bp_int(p, v, f)
  724.     char *p;
  725.     PyObject *v;
  726.     const formatdef *f;
  727. {
  728.     long x;
  729.     int i;
  730.     if (get_long(v, &x) < 0)
  731.         return -1;
  732.     i = f->size;
  733.     do {
  734.         p[--i] = (char)x;
  735.         x >>= 8;
  736.     } while (i > 0);
  737.     return 0;
  738. }
  739.  
  740. static int
  741. bp_uint(p, v, f)
  742.     char *p;
  743.     PyObject *v;
  744.     const formatdef *f;
  745. {
  746.     unsigned long x;
  747.     int i;
  748.     if (get_ulong(v, &x) < 0)
  749.         return -1;
  750.     i = f->size;
  751.     do {
  752.         p[--i] = (char)x;
  753.         x >>= 8;
  754.     } while (i > 0);
  755.     return 0;
  756. }
  757.  
  758. static int
  759. bp_float(p, v, f)
  760.     char *p;
  761.     PyObject *v;
  762.     const formatdef *f;
  763. {
  764.     double x = PyFloat_AsDouble(v);
  765.     if (x == -1 && PyErr_Occurred()) {
  766.         PyErr_SetString(StructError,
  767.                 "required argument is not a float");
  768.         return -1;
  769.     }
  770.     return pack_float(x, p, 1);
  771. }
  772.  
  773. static int
  774. bp_double(p, v, f)
  775.     char *p;
  776.     PyObject *v;
  777.     const formatdef *f;
  778. {
  779.     double x = PyFloat_AsDouble(v);
  780.     if (x == -1 && PyErr_Occurred()) {
  781.         PyErr_SetString(StructError,
  782.                 "required argument is not a float");
  783.         return -1;
  784.     }
  785.     return pack_double(x, p, 1);
  786. }
  787.  
  788. static formatdef bigendian_table[] = {
  789.     {'x',    1,        0,        NULL},
  790.     {'b',    1,        0,        bu_int,        bp_int},
  791.     {'B',    1,        0,        bu_uint,    bp_int},
  792.     {'c',    1,        0,        nu_char,    np_char},
  793.     {'s',    1,        0,        NULL},
  794.     {'p',    1,        0,        NULL},
  795.     {'h',    2,        0,        bu_int,        bp_int},
  796.     {'H',    2,        0,        bu_uint,    bp_uint},
  797.     {'i',    4,        0,        bu_int,        bp_int},
  798.     {'I',    4,        0,        bu_uint,    bp_uint},
  799.     {'l',    4,        0,        bu_int,        bp_int},
  800.     {'L',    4,        0,        bu_uint,    bp_uint},
  801.     {'f',    4,        0,        bu_float,    bp_float},
  802.     {'d',    8,        0,        bu_double,    bp_double},
  803.     {0}
  804. };
  805.  
  806. static PyObject *
  807. lu_int(p, f)
  808.     const char *p;
  809.     const formatdef *f;
  810. {
  811.     long x = 0;
  812.     int i = f->size;
  813.     do {
  814.         x = (x<<8) | (p[--i] & 0xFF);
  815.     } while (i > 0);
  816.     i = 8*(sizeof(long) - f->size);
  817.     if (i) {
  818.         x <<= i;
  819.         x >>= i;
  820.     }
  821.     return PyInt_FromLong(x);
  822. }
  823.  
  824. static PyObject *
  825. lu_uint(p, f)
  826.     const char *p;
  827.     const formatdef *f;
  828. {
  829.     unsigned long x = 0;
  830.     int i = f->size;
  831.     do {
  832.         x = (x<<8) | (p[--i] & 0xFF);
  833.     } while (i > 0);
  834.     if (f->size >= 4)
  835.         return PyLong_FromUnsignedLong(x);
  836.     else
  837.         return PyInt_FromLong((long)x);
  838. }
  839.  
  840. static PyObject *
  841. lu_float(p, f)
  842.     const char *p;
  843.     const formatdef *f;
  844. {
  845.     return unpack_float(p+3, -1);
  846. }
  847.  
  848. static PyObject *
  849. lu_double(p, f)
  850.     const char *p;
  851.     const formatdef *f;
  852. {
  853.     return unpack_double(p+7, -1);
  854. }
  855.  
  856. static int
  857. lp_int(p, v, f)
  858.     char *p;
  859.     PyObject *v;
  860.     const formatdef *f;
  861. {
  862.     long x;
  863.     int i;
  864.     if (get_long(v, &x) < 0)
  865.         return -1;
  866.     i = f->size;
  867.     do {
  868.         *p++ = (char)x;
  869.         x >>= 8;
  870.     } while (--i > 0);
  871.     return 0;
  872. }
  873.  
  874. static int
  875. lp_uint(p, v, f)
  876.     char *p;
  877.     PyObject *v;
  878.     const formatdef *f;
  879. {
  880.     unsigned long x;
  881.     int i;
  882.     if (get_ulong(v, &x) < 0)
  883.         return -1;
  884.     i = f->size;
  885.     do {
  886.         *p++ = (char)x;
  887.         x >>= 8;
  888.     } while (--i > 0);
  889.     return 0;
  890. }
  891.  
  892. static int
  893. lp_float(p, v, f)
  894.     char *p;
  895.     PyObject *v;
  896.     const formatdef *f;
  897. {
  898.     double x = PyFloat_AsDouble(v);
  899.     if (x == -1 && PyErr_Occurred()) {
  900.         PyErr_SetString(StructError,
  901.                 "required argument is not a float");
  902.         return -1;
  903.     }
  904.     return pack_float(x, p+3, -1);
  905. }
  906.  
  907. static int
  908. lp_double(p, v, f)
  909.     char *p;
  910.     PyObject *v;
  911.     const formatdef *f;
  912. {
  913.     double x = PyFloat_AsDouble(v);
  914.     if (x == -1 && PyErr_Occurred()) {
  915.         PyErr_SetString(StructError,
  916.                 "required argument is not a float");
  917.         return -1;
  918.     }
  919.     return pack_double(x, p+7, -1);
  920. }
  921.  
  922. static formatdef lilendian_table[] = {
  923.     {'x',    1,        0,        NULL},
  924.     {'b',    1,        0,        lu_int,        lp_int},
  925.     {'B',    1,        0,        lu_uint,    lp_int},
  926.     {'c',    1,        0,        nu_char,    np_char},
  927.     {'s',    1,        0,        NULL},
  928.     {'p',    1,        0,        NULL},
  929.     {'h',    2,        0,        lu_int,        lp_int},
  930.     {'H',    2,        0,        lu_uint,    lp_uint},
  931.     {'i',    4,        0,        lu_int,        lp_int},
  932.     {'I',    4,        0,        lu_uint,    lp_uint},
  933.     {'l',    4,        0,        lu_int,        lp_int},
  934.     {'L',    4,        0,        lu_uint,    lp_uint},
  935.     {'f',    4,        0,        lu_float,    lp_float},
  936.     {'d',    8,        0,        lu_double,    lp_double},
  937.     {0}
  938. };
  939.  
  940.  
  941. static const formatdef *
  942. whichtable(pfmt)
  943.     const char **pfmt;
  944. {
  945.     const char *fmt = (*pfmt)++; /* May be backed out of later */
  946.     switch (*fmt) {
  947.     case '<':
  948.         return lilendian_table;
  949.     case '>':
  950.     case '!': /* Network byte order is big-endian */
  951.         return bigendian_table;
  952.     case '=': { /* Host byte order -- different from native in aligment! */
  953.         int n = 1;
  954.         char *p = (char *) &n;
  955.         if (*p == 1)
  956.             return lilendian_table;
  957.         else
  958.             return bigendian_table;
  959.     }
  960.     default:
  961.         --*pfmt; /* Back out of pointer increment */
  962.         /* Fall through */
  963.     case '@':
  964.         return native_table;
  965.     }
  966. }
  967.  
  968.  
  969. /* Get the table entry for a format code */
  970.  
  971. static const formatdef *
  972. getentry(c, f)
  973.     int c;
  974.     const formatdef *f;
  975. {
  976.     for (; f->format != '\0'; f++) {
  977.         if (f->format == c) {
  978.             return f;
  979.         }
  980.     }
  981.     PyErr_SetString(StructError, "bad char in struct format");
  982.     return NULL;
  983. }
  984.  
  985.  
  986. /* Align a size according to a format code */
  987.  
  988. static int
  989. align(size, c, e)
  990.     int size;
  991.     int c;
  992.     const formatdef *e;
  993. {
  994.     if (e->format == c) {
  995.         if (e->alignment) {
  996.             size = ((size + e->alignment - 1)
  997.                 / e->alignment)
  998.                 * e->alignment;
  999.         }
  1000.     }
  1001.     return size;
  1002. }
  1003.  
  1004.  
  1005. /* calculate the size of a format string */
  1006.  
  1007. static int
  1008. calcsize(fmt, f)
  1009.     const char *fmt;
  1010.     const formatdef *f;
  1011. {
  1012.     const formatdef *e;
  1013.     const char *s;
  1014.     char c;
  1015.     int size,  num, itemsize, x;
  1016.  
  1017.     s = fmt;
  1018.     size = 0;
  1019.     while ((c = *s++) != '\0') {
  1020.         if (isspace((int)c))
  1021.             continue;
  1022.         if ('0' <= c && c <= '9') {
  1023.             num = c - '0';
  1024.             while ('0' <= (c = *s++) && c <= '9') {
  1025.                 x = num*10 + (c - '0');
  1026.                 if (x/10 != num) {
  1027.                     PyErr_SetString(
  1028.                         StructError,
  1029.                         "overflow in item count");
  1030.                     return -1;
  1031.                 }
  1032.                 num = x;
  1033.             }
  1034.             if (c == '\0')
  1035.                 break;
  1036.         }
  1037.         else
  1038.             num = 1;
  1039.         
  1040.         e = getentry(c, f);
  1041.         if (e == NULL)
  1042.             return -1;
  1043.         itemsize = e->size;
  1044.         size = align(size, c, e);
  1045.         x = num * itemsize;
  1046.         size += x;
  1047.         if (x/itemsize != num || size < 0) {
  1048.             PyErr_SetString(StructError,
  1049.                                         "total struct size too long");
  1050.             return -1;
  1051.         }
  1052.     }
  1053.  
  1054.     return size;
  1055. }
  1056.  
  1057.  
  1058. static char calcsize__doc__[] = "\
  1059. calcsize(fmt) -> int\n\
  1060. Return size of C struct described by format string fmt.\n\
  1061. See struct.__doc__ for more on format strings.";
  1062.  
  1063. static PyObject *
  1064. struct_calcsize(self, args)
  1065.     PyObject *self; /* Not used */
  1066.     PyObject *args;
  1067. {
  1068.     char *fmt;
  1069.     const formatdef *f;
  1070.     int size;
  1071.  
  1072.     if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
  1073.         return NULL;
  1074.     f = whichtable(&fmt);
  1075.     size = calcsize(fmt, f);
  1076.     if (size < 0)
  1077.         return NULL;
  1078.     return PyInt_FromLong((long)size);
  1079. }
  1080.  
  1081.  
  1082. static char pack__doc__[] = "\
  1083. pack(fmt, v1, v2, ...) -> string\n\
  1084. Return string containing values v1, v2, ... packed according to fmt.\n\
  1085. See struct.__doc__ for more on format strings.";
  1086.  
  1087. static PyObject *
  1088. struct_pack(self, args)
  1089.     PyObject *self; /* Not used */
  1090.     PyObject *args;
  1091. {
  1092.     const formatdef *f, *e;
  1093.     PyObject *format, *result, *v;
  1094.     char *fmt;
  1095.     int size, num;
  1096.     int i, n;
  1097.     char *s, *res, *restart, *nres;
  1098.     char c;
  1099.  
  1100.     if (args == NULL || !PyTuple_Check(args) ||
  1101.         (n = PyTuple_Size(args)) < 1)
  1102.         {
  1103.         PyErr_BadArgument();
  1104.         return NULL;
  1105.     }
  1106.     format = PyTuple_GetItem(args, 0);
  1107.     if (!PyArg_Parse(format, "s", &fmt))
  1108.         return NULL;
  1109.     f = whichtable(&fmt);
  1110.     size = calcsize(fmt, f);
  1111.     if (size < 0)
  1112.         return NULL;
  1113.     result = PyString_FromStringAndSize((char *)NULL, size);
  1114.     if (result == NULL)
  1115.         return NULL;
  1116.  
  1117.     s = fmt;
  1118.     i = 1;
  1119.     res = restart = PyString_AsString(result);
  1120.  
  1121.     while ((c = *s++) != '\0') {
  1122.         if (isspace((int)c))
  1123.             continue;
  1124.         if ('0' <= c && c <= '9') {
  1125.             num = c - '0';
  1126.             while ('0' <= (c = *s++) && c <= '9')
  1127.                    num = num*10 + (c - '0');
  1128.             if (c == '\0')
  1129.                 break;
  1130.         }
  1131.         else
  1132.             num = 1;
  1133.  
  1134.         e = getentry(c, f);
  1135.         if (e == NULL)
  1136.             goto fail;
  1137.         nres = restart + align((int)(res-restart), c, e);
  1138.         /* Fill padd bytes with zeros */
  1139.         while (res < nres)
  1140.             *res++ = '\0';
  1141.         if (num == 0 && c != 's')
  1142.             continue;
  1143.         do {
  1144.             if (c == 'x') {
  1145.                 /* doesn't consume arguments */
  1146.                 memset(res, '\0', num);
  1147.                 res += num;
  1148.                 break;
  1149.             }
  1150.             if (i >= n) {
  1151.                 PyErr_SetString(StructError,
  1152.                     "insufficient arguments to pack");
  1153.                 goto fail;
  1154.                 }
  1155.             v = PyTuple_GetItem(args, i++);
  1156.             if (v == NULL)
  1157.                 goto fail;
  1158.             if (c == 's') {
  1159.                 /* num is string size, not repeat count */
  1160.                 int n;
  1161.                 if (!PyString_Check(v)) {
  1162.                     PyErr_SetString(StructError,
  1163.                       "argument for 's' must be a string");
  1164.                     goto fail;
  1165.                 }
  1166.                 n = PyString_Size(v);
  1167.                 if (n > num)
  1168.                     n = num;
  1169.                 if (n > 0)
  1170.                     memcpy(res, PyString_AsString(v), n);
  1171.                 if (n < num)
  1172.                     memset(res+n, '\0', num-n);
  1173.                 res += num;
  1174.                 break;
  1175.             }
  1176.             else if (c == 'p') {
  1177.                 /* num is string size + 1,
  1178.                    to fit in the count byte */
  1179.                 int n;
  1180.                 num--; /* now num is max string size */
  1181.                 if (!PyString_Check(v)) {
  1182.                     PyErr_SetString(StructError,
  1183.                       "argument for 'p' must be a string");
  1184.                     goto fail;
  1185.                 }
  1186.                 n = PyString_Size(v);
  1187.                 if (n > num)
  1188.                     n = num;
  1189.                 if (n > 0)
  1190.                     memcpy(res+1, PyString_AsString(v), n);
  1191.                 if (n < num)
  1192.                     /* no real need, just to be nice */
  1193.                     memset(res+1+n, '\0', num-n);
  1194.                 *res++ = n; /* store the length byte */
  1195.                 res += num;
  1196.                 break;
  1197.             }
  1198.             else {
  1199.                 if (e->pack(res, v, e) < 0)
  1200.                     goto fail;
  1201.                 res += e->size;
  1202.             }
  1203.         } while (--num > 0);
  1204.     }
  1205.  
  1206.     if (i < n) {
  1207.         PyErr_SetString(StructError,
  1208.                 "too many arguments for pack format");
  1209.         goto fail;
  1210.     }
  1211.  
  1212.     return result;
  1213.  
  1214.  fail:
  1215.     Py_DECREF(result);
  1216.     return NULL;
  1217. }
  1218.  
  1219.  
  1220. static char unpack__doc__[] = "\
  1221. unpack(fmt, string) -> (v1, v2, ...)\n\
  1222. Unpack the string, containing packed C structure data, according\n\
  1223. to fmt.  Requires len(string)==calcsize(fmt).\n\
  1224. See struct.__doc__ for more on format strings.";
  1225.  
  1226. static PyObject *
  1227. struct_unpack(self, args)
  1228.     PyObject *self; /* Not used */
  1229.     PyObject *args;
  1230. {
  1231.     const formatdef *f, *e;
  1232.     char *str, *start, *fmt, *s;
  1233.     char c;
  1234.     int len, size, num;
  1235.     PyObject *res, *v;
  1236.  
  1237.     if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
  1238.         return NULL;
  1239.     f = whichtable(&fmt);
  1240.     size = calcsize(fmt, f);
  1241.     if (size < 0)
  1242.         return NULL;
  1243.     if (size != len) {
  1244.         PyErr_SetString(StructError,
  1245.                 "unpack str size does not match format");
  1246.         return NULL;
  1247.     }
  1248.     res = PyList_New(0);
  1249.     if (res == NULL)
  1250.         return NULL;
  1251.     str = start;
  1252.     s = fmt;
  1253.     while ((c = *s++) != '\0') {
  1254.         if (isspace((int)c))
  1255.             continue;
  1256.         if ('0' <= c && c <= '9') {
  1257.             num = c - '0';
  1258.             while ('0' <= (c = *s++) && c <= '9')
  1259.                    num = num*10 + (c - '0');
  1260.             if (c == '\0')
  1261.                 break;
  1262.         }
  1263.         else
  1264.             num = 1;
  1265.  
  1266.         e = getentry(c, f);
  1267.         if (e == NULL)
  1268.             goto fail;
  1269.         str = start + align((int)(str-start), c, e);
  1270.         if (num == 0 && c != 's')
  1271.             continue;
  1272.  
  1273.         do {
  1274.             if (c == 'x') {
  1275.                 str += num;
  1276.                 break;
  1277.             }
  1278.             if (c == 's') {
  1279.                 /* num is string size, not repeat count */
  1280.                 v = PyString_FromStringAndSize(str, num);
  1281.                 if (v == NULL)
  1282.                     goto fail;
  1283.                 str += num;
  1284.                 num = 0;
  1285.             }
  1286.             else if (c == 'p') {
  1287.                 /* num is string buffer size,
  1288.                    not repeat count */
  1289.                 int n = *(unsigned char*)str;
  1290.                 /* first byte (unsigned) is string size */
  1291.                 if (n >= num)
  1292.                     n = num-1;
  1293.                 v = PyString_FromStringAndSize(str+1, n);
  1294.                 if (v == NULL)
  1295.                     goto fail;
  1296.                 str += num;
  1297.                 num = 0;
  1298.             }
  1299.             else {
  1300.                 v = e->unpack(str, e);
  1301.                 if (v == NULL)
  1302.                     goto fail;
  1303.                 str += e->size;
  1304.             }
  1305.             if (v == NULL || PyList_Append(res, v) < 0)
  1306.                 goto fail;
  1307.             Py_DECREF(v);
  1308.         } while (--num > 0);
  1309.     }
  1310.  
  1311.     v = PyList_AsTuple(res);
  1312.     Py_DECREF(res);
  1313.     return v;
  1314.  
  1315.  fail:
  1316.     Py_DECREF(res);
  1317.     return NULL;
  1318. }
  1319.  
  1320.  
  1321. /* List of functions */
  1322.  
  1323. static PyMethodDef struct_methods[] = {
  1324.     {"calcsize",    struct_calcsize,    METH_VARARGS, calcsize__doc__},
  1325.     {"pack",    struct_pack,        METH_VARARGS, pack__doc__},
  1326.     {"unpack",    struct_unpack,        METH_VARARGS, unpack__doc__},
  1327.     {NULL,        NULL}        /* sentinel */
  1328. };
  1329.  
  1330.  
  1331. /* Module initialization */
  1332.  
  1333. DL_EXPORT(void)
  1334. initstruct()
  1335. {
  1336.     PyObject *m, *d;
  1337.  
  1338.     /* Create the module and add the functions */
  1339.     m = Py_InitModule4("struct", struct_methods, struct__doc__,
  1340.                (PyObject*)NULL, PYTHON_API_VERSION);
  1341.  
  1342.     /* Add some symbolic constants to the module */
  1343.     d = PyModule_GetDict(m);
  1344.     StructError = PyErr_NewException("struct.error", NULL, NULL);
  1345.     if (StructError == NULL)
  1346.         return;
  1347.     PyDict_SetItemString(d, "error", StructError);
  1348. }
  1349.